package com.apex.sdk.ui;

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Xfermode;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.RadioGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatButton;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.FileProvider;

import com.apex.bluetooth.callback.OtaCallback;
import com.apex.bluetooth.core.EABleManager;
import com.apex.bluetooth.model.EABleOta;
import com.apex.sdk.R;
import com.apex.sdk.databinding.ActivityTitanCustomDialBinding;
import com.apex.sdk.dialog.DialSelectPicDialog;
import com.apex.sdk.dialog.WaitingDialog;
import com.apex.sdk.utils.WatchFaceUtils;
import com.bumptech.glide.Glide;


import com.smartcomm.lz4.PreLz4;
import com.theartofdev.edmodo.cropper.CropImage;
import com.theartofdev.edmodo.cropper.CropImageView;


import net.jpountz.lz4.LZ4Compressor;
import net.jpountz.lz4.LZ4Factory;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;


public class TitanCustomDialActivity extends AppCompatActivity {
    final String TAG = this.getClass().getSimpleName();

    private WaitingDialog waitingDialog;
    private DialSelectPicDialog dialSelectPicDialog;
    private final int PERMISSION_CODE = 3;
    private final int IMAGE_REQUEST_CODE = 0;
    private final int CAMERA_REQUEST_CODE = 1;
    private final int RESULT_REQUEST_CODE = 2;
    private final String DIAL_BG = "dial_bg.png";
    private Uri imageUri;
    int oriFileSize;
    int styleType;
    String backPath;
    private String dialFilePath;
    String tempOtaWatchFaceFileName = "custom_watchface_temp.bin";
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == 0x43) {
                if (TextUtils.isEmpty(dialFilePath) || !new File(dialFilePath).exists()) {
                    Log.e(TAG, "表盘文件不存在");
                    if (waitingDialog != null) {
                        if (waitingDialog.isShowing()) {
                            waitingDialog.dismiss();
                        }
                    }
                } else {
                    EABleOta eaBleOta = new EABleOta();
                    eaBleOta.setFilePath(dialFilePath);
                    eaBleOta.setOtaType(EABleOta.OtaType.user_wf);
                    eaBleOta.setVersionCode(0);
                    eaBleOta.setCustomDialStyle(oriFileSize);
                    List<EABleOta> otaList = new ArrayList<>();
                    otaList.add(eaBleOta);

                    EABleManager.getInstance().otaUpdate(otaList, new OtaCallback() {
                        @Override
                        public void success() {
                            Log.e(TAG, "OTA成功");
                            if (mHandler != null) {
                                mHandler.sendEmptyMessage(0x42);
                            }

                        }

                        @Override
                        public void progress(int progress) {
                            Log.e(TAG, "OTA进度:" + progress);

                        }

                        @Override
                        public void mutualFail(int errorCode) {
                            Log.e(TAG, "OTA失败");
                            if (mHandler != null) {
                                mHandler.sendEmptyMessage(0x42);
                            }
                        }
                    });

                }
            } else if (msg.what == 0x42) {
                if (waitingDialog != null) {
                    if (waitingDialog.isShowing()) {
                        waitingDialog.dismiss();
                    }
                }
            }
        }
    };
    ActivityTitanCustomDialBinding activityTitanCustomDialBinding;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityTitanCustomDialBinding = ActivityTitanCustomDialBinding.inflate(getLayoutInflater());
        setContentView(activityTitanCustomDialBinding.getRoot());
        activityTitanCustomDialBinding.tool.setNavigationIcon(R.mipmap.exit_page);
        setSupportActionBar(activityTitanCustomDialBinding.tool);
        getSupportActionBar().setTitle(null);
        activityTitanCustomDialBinding.tool.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        styleType = activityTitanCustomDialBinding.styleSelect.getCheckedRadioButtonId();
        activityTitanCustomDialBinding.styleSelect.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                styleType = checkedId;
                showPreviewImage();
            }
        });
        showPreviewImage();
        activityTitanCustomDialBinding.selectBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED ) {
                    initDialog();
                } else {
                    requestPermissions(new String[]{Manifest.permission.CAMERA}, PERMISSION_CODE);
                }
            }
        });
        activityTitanCustomDialBinding.install.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (waitingDialog == null) {
                    waitingDialog = new WaitingDialog(TitanCustomDialActivity.this);
                }
                if (waitingDialog.isShowing()) {
                    return;
                }
                waitingDialog.show();
                new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        try {
                            String nFilePath = onCustomWatchFace();
                            if (!TextUtils.isEmpty(nFilePath) && !"".equalsIgnoreCase(nFilePath)) {
                                Log.e(TAG, "新生成的文件存在:" + nFilePath);
                                oriFileSize = (int) new File(nFilePath).length();
                                String fName = System.currentTimeMillis() + ".bin";
                                //先处理文件流
                                Log.e(TAG, "开始进行流处理");
                                //    String iFilePath = EABleManager.getInstance().handleTitanOnlineDial(getExternalCacheDir().getAbsolutePath(), tempOtaWatchFaceFileName);
                                //    if (!TextUtils.isEmpty(iFilePath) && new File(iFilePath).exists()) {
                                File compressFile = new File(getExternalCacheDir(), "compress_" + fName);
                                if (!compressFile.exists()) {
                                    compressFile.createNewFile();
                                }
                                Log.e(TAG, "开始进行压缩");
                                int result = new PreLz4().editData(nFilePath, compressFile.getAbsolutePath());
                                if (result == 0) {
                                    //将文件保存
                                    dialFilePath = compressFile.getAbsolutePath();
                                    if (mHandler != null) {
                                        mHandler.sendEmptyMessage(0x43);
                                    }
                                    return;
                                }
                                Log.e(TAG, "压缩失败");
                                //   }
                            }
                        } catch (Exception e) {
                            Log.e(TAG, "读写文件出现异常：" + e.getMessage());

                        }
                    }
                }.start();

            }
        });

    }

    private void showPreviewImage() {
        if (!TextUtils.isEmpty(backPath) && !"".equalsIgnoreCase(backPath)) {
            Glide.with(TitanCustomDialActivity.this).load(backPath).into(activityTitanCustomDialBinding.previewBack);
        }
        if (styleType == R.id.style_1) {
            Glide.with(TitanCustomDialActivity.this).load(R.mipmap.face_cus_01_dark_preview).into(activityTitanCustomDialBinding.previewFont);

        } else if (styleType == R.id.style_2) {
            Glide.with(TitanCustomDialActivity.this).load(R.mipmap.face_cus_01_light_preview).into(activityTitanCustomDialBinding.previewFont);
        }
    }

    private void initDialog() {
        if (dialSelectPicDialog == null) {
            final DialSelectPicDialog.Builder builder = new DialSelectPicDialog.Builder(TitanCustomDialActivity.this);
            builder.setAlbumonButton(new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent(Intent.ACTION_PICK, null);
                    intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                    startActivityForResult(intent, IMAGE_REQUEST_CODE);
                    dialog.dismiss();
                }
            });
            builder.setPhotoButton(new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    if (hasSdcard()) {
                        File outputImage = new File(getExternalCacheDir(), DIAL_BG);
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                            imageUri = FileProvider.getUriForFile(TitanCustomDialActivity.this, getPackageName() + ".fileProvider", outputImage);
                        } else {
                            imageUri = Uri.fromFile(outputImage);
                        }
                        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                        startActivityForResult(intent, CAMERA_REQUEST_CODE);
                    } else {
                        Log.e(TAG, "外置SDK不存在");
                    }
                    dialog.dismiss();
                }
            });
            builder.setCancelButton(new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            dialSelectPicDialog = builder.create();
        }
        if (!dialSelectPicDialog.isShowing()) {
            dialSelectPicDialog.show();
        }
    }

    private boolean hasSdcard() {
        String state = Environment.getExternalStorageState();
        if (state.equals(Environment.MEDIA_MOUNTED)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        boolean hasPermission = true;
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                hasPermission = false;
                break;
            }
        }
        if (hasPermission) {
            initDialog();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (resultCode != RESULT_CANCELED) {

            switch (requestCode) {
                case IMAGE_REQUEST_CODE://
                    Log.e(TAG, "从相册获取图片并剪切");
                    startPhotoZoom(data.getData());
                    break;
                case CAMERA_REQUEST_CODE:
                    if (hasSdcard()) {
                        startPhotoZoom(Uri.fromFile(new File(getExternalCacheDir(), DIAL_BG)));
                    } else {
                        startPhotoZoom(Uri.fromFile(new File(getCacheDir(), DIAL_BG)));
                    }

                    break;
                case RESULT_REQUEST_CODE:
                    break;
                case CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE:
                    CropImage.ActivityResult result = CropImage.getActivityResult(data);
                    Uri resultUri = result.getUri();
                    if (resultUri == null) {
                        return;
                    }
                    backPath = resultUri.getPath();
                    showPreviewImage();


                    break;
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    private void startPhotoZoom(Uri uri) {
        CropImage.activity(uri)
                .setGuidelines(CropImageView.Guidelines.ON)
                .setRequestedSize(240, 240, CropImageView.RequestSizeOptions.RESIZE_EXACT)//解决有些图片裁剪得出239*239而导致更换不了表盘背景的问题
                .setMinCropResultSize(240, 240)
                .setAspectRatio(240, 240)//根据手表屏幕长方形或正方形进行背景裁剪，避免背景图被拉伸
                .start(this);

    }

    private String onCustomWatchFace() {
        //将表盘文件读出来
        try {
            InputStream inputStream = null;
            if (styleType == R.id.style_1) {
                inputStream = getAssets().open("titan_face_cus_01_d.bin");
            } else if (styleType == R.id.style_2) {
                inputStream = getAssets().open("titan_face_cus_01_l.bin");
            }
            if (inputStream != null) {
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                byte[] readByte = new byte[1024];
                int len;
                while ((len = inputStream.read(readByte)) != -1) {
                    byteArrayOutputStream.write(readByte, 0, len);
                }
                byte[] fileByte = byteArrayOutputStream.toByteArray();
                inputStream.close();
                byteArrayOutputStream.close();
                return transformBitmap(fileByte);
            }
        } catch (Exception e) {
            Log.e(TAG, "读写文件出现异常：" + e.getMessage());

        }
        return null;
    }

    private String transformBitmap(byte[] dataBytes) {
        try {
            //创建一个240X240的图片
            final Bitmap cBitmap = createThumbnail();
            if (mHandler != null) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Glide.with(TitanCustomDialActivity.this).load(cBitmap).into(activityTitanCustomDialBinding.selectBack);
                    }
                });
            }
            Log.e(TAG, "创建了一个bitmap,240*240");
            byte[] pByte = WatchFaceUtils.INSTANCE.getPicturePixel(cBitmap);
            Log.e(TAG, "获取了bitmap的图片像素:" + pByte.length);
            System.arraycopy(pByte, 0, dataBytes, 4, pByte.length);
            Bitmap bgBitmap = createBackImage();
            byte[] bgPicturePixel = WatchFaceUtils.INSTANCE.getPicturePixel(bgBitmap);
            System.arraycopy(bgPicturePixel, 0, dataBytes, 115212, bgPicturePixel.length);
            Log.e(TAG, "获取了背景图的像素：" + bgPicturePixel.length);
            File otaCacheSourceFile = new File(getExternalCacheDir(), tempOtaWatchFaceFileName);
            if (otaCacheSourceFile.exists()) {
                otaCacheSourceFile.delete();
            }
            otaCacheSourceFile.createNewFile();
            FileOutputStream outputStream = new FileOutputStream(otaCacheSourceFile);
            Log.e(TAG, "将数据保存成文件");
            outputStream.write(dataBytes, 0, dataBytes.length);
            outputStream.close();
            return otaCacheSourceFile.getAbsolutePath();
        } catch (Exception e) {
            Log.e(TAG, "出现异常：" + e.getMessage());

        }
        return null;
    }

    private Bitmap createThumbnail() {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;
        Bitmap fontBit;
        if (styleType == R.id.style_1) {
            fontBit = BitmapFactory.decodeResource(getResources(), R.mipmap.face_cus_01_dark_preview, options);
        } else {
            fontBit = BitmapFactory.decodeResource(getResources(), R.mipmap.face_cus_01_light_preview, options);
        }
        Bitmap backBit = BitmapFactory.decodeFile(backPath, options);
        Paint paint = new Paint();
        paint.setColor(Color.CYAN);
        paint.setAntiAlias(true);
        //创建一个缩略图
        Bitmap bitmap = Bitmap.createBitmap(240, 240, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawBitmap(backBit, new Rect(0, 0, backBit.getWidth(), backBit.getHeight()), new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), paint);
        canvas.drawBitmap(fontBit, new Rect(0, 0, fontBit.getWidth(), fontBit.getHeight()), new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), paint);
        return getCircleImage(bitmap);
    }

    private Bitmap getCircleImage(Bitmap bitmap) {
        Bitmap cBitmap = Bitmap.createBitmap(240, 240, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(cBitmap);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas.drawCircle(120, 120, 120, paint);
        paint.reset();
        paint.setAntiAlias(true);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, 0, 0, paint);
        bitmap.recycle();
        return cBitmap;

    }

    private Bitmap createBackImage() {
        BitmapFactory.Options options1 = new BitmapFactory.Options();
        options1.inPreferredConfig = Bitmap.Config.RGB_565;
        Bitmap pgBitmap = BitmapFactory.decodeFile(backPath, options1);
        Bitmap mBgPicBitmap = Bitmap.createScaledBitmap(pgBitmap, 390, 390, true);
        return mBgPicBitmap;
    }

    @Override
    protected void onDestroy() {
        if (mHandler != null) {
            mHandler.removeCallbacksAndMessages(null);
            mHandler = null;
        }
        if (waitingDialog != null) {
            waitingDialog.dismiss();
            waitingDialog = null;
        }

        super.onDestroy();
    }

}
